<template>
  <div id="topoChart">
    <div class="operating">
      <div class="tools-title">
        <h5>指针</h5>
      </div>
      <div class="choose-btn-group">
        <div class="btn" @click="changeMode('edit')" title="选择">
          <img src="@/assets/images/choose.png">
          <span>选择</span>
        </div>
        <div class="btn" @click="addPolyLine" title="连接">
          <img src="@/assets/images/link.png">
          <span>连接</span>
        </div>
      </div>
      <div class="btn-group">
        <div class="btn" @click="changeMode('drag')" title="拖拽画布" style="width:50%;padding:10px 0;">
          <img src="@/assets/images/drag.png">
          <span>拖拽画布</span>
        </div>
      </div>
      <div class="tools-title">
        <h5>元件库</h5>
      </div>
      <div class="btn-group">
        <div class="btn" @click="addBusbar" title="母线">
          <img src="@/assets/images/transformer.png">
          <span>母线</span>
        </div>
        <div class="btn" @click="addTransformer" title="变压器">
          <img src="@/assets/images/transformer.png">
          <span>变压器</span>
        </div>
        <div class="btn" @click="addSwitch" title="开关">
          <img src="@/assets/images/transformer.png">
          <span>开关</span>
        </div>
      </div>
      <div class="tools-title">
        <h5>操作</h5>
      </div>
      <div class="btn-group">
        <div class="btn" @click="del" style="margin-top: 5px;" title="删除">
          <i class="el-icon-delete"></i>
        </div>
        <div class="btn" @click="save" title="保存">
          <i class="iconfont icon-baocun"></i>
        </div>
      </div>
      <div class="tools-title">
        <h5>数值管理</h5>
      </div>
      <div class="btn-group">
        <div class="btn" @click="del" style="margin-top: 5px;" title="支路类型管理">
          <span style="color:#0099CC">支路类型管理</span>
        </div>
      </div>
    </div>
    <div class="info-box">
      <div class="title">
        <span>{{ infoTitle }}属性</span>
      </div>
      <div class="content">
        <div v-show="isBlank" style="padding: 4px 0;">
          <el-input
            size="mini"
            v-model="workflowName"
            placeholder="请输入拓扑图名称..."
          ></el-input>
        </div>
        <el-checkbox v-if="isBlank" v-model="checked"
          >网格对齐</el-checkbox
        >
        <el-form v-else label-position="left" label-width="60px">
          <el-form-item v-if="isNode !== true" label="动作">
            <el-select
              v-model="action"
              size="mini"
              filterable
              placeholder="绑定动作"
              value=""
            >
              <el-option
                v-for="item in actionList"
                :key="item.id"
                :label="item.label"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <!-- 线-->
          <el-form-item v-show="isNode === true" label="名称">
            <el-input ref="inputFocusRef" size="mini" v-model="name"></el-input>
          </el-form-item>
          <el-form-item v-show="isNode === true" label="功能">
            <el-select
              v-model="func"
              size="mini"
              filterable
              placeholder="绑定功能"
            >
              <el-option
                v-for="item in funcList"
                :key="item.id"
                :label="item.label"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-show="isNode === true" label="账号">
            <el-select
              v-model="account"
              size="mini"
              filterable
              multiple
              collapse-tags
              placeholder="绑定账号"
              value=""
            >
              <el-option
                v-for="item in accountList"
                :key="item.id"
                :label="item.label"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-show="isNode === true" label="拓扑图">
            <el-select
              v-model="workflow"
              size="mini"
              filterable
              clearable
              placeholder="绑定拓扑图"
              value=""
            >
              <el-option
                v-for="item in workflowList"
                :key="item.id"
                :label="item.label"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-show="isNode === true" label="类型">
            <el-select
              v-model="nodeType"
              size="mini"
              filterable
              placeholder="请选择类型"
              value=""
            >
              <el-option
                v-for="item in nodeTypeList"
                :key="item.id"
                :label="item.label"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="颜色">
            <el-color-picker v-model="color"></el-color-picker>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import G6 from '@antv/g6';
export default {
  name: 'topo',
  props: {
    actionList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    funcList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    accountList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    workflowList: {
      type: Array,
      default: function() {
        return [];
      }
    },
    nodeTypeList: {
      type: Array,
      default: () => {
        return [
          { id: 0, label: '普通节点' },
          { id: 1, label: '入口节点' },
          { id: 2, label: '出口节点' }
        ];
      }
    }
  },
  data() {
    return {
      canvasWidth: 0,
      action: '',
      name: '',
      func: '',
      account: '',
      workflow: '',
      nodeType: 0,
      color: '',
      graph: '',
      workflowName: '',
      activation: '', // 当前激活的节点
      isNode: false, // 当前是节点
      isBlank: true, // 当前是空白区
      checked: true, // 网格对齐
      infoTitle: '画布', // 属性标题
      oldColor: '', // 获取节点本身颜色
      type: '' // 有值为编辑状态
    };
  },
  watch: {
    /**
     * 监听输入框
     */
    action: function() {
      this.update();
    },
    name: function() {
      this.update();
    },
    func: function() {
      this.update();
    },
    account: function() {
      this.update();
    },
    workflow: function() {
      this.update();
    },
    nodeType: function() {
      this.update();
    },
    color: function() {
      this.update();
    },
    /**
     * 网格切换
     */
    checked: function() {
      const _saveData = this.graph.save();
      this.graph.destroy(); // 销毁画布
      this.initG6();
      this.graph.read(_saveData);
      this.graph.render();
    }
  },
  mounted() {
    this.canvasWidth = parseInt(window.getComputedStyle(document.getElementById('topoChart')).width) - 20;
    this.initG6();
  },
  methods: {
    initG6() {
      const self = this;
      // let grid;
      // if (self.checked) {
      //   grid = {
      //     forceAlign: true, // 是否支持网格对齐
      //     cell: 25 // 网格大小
      //   };
      // } else {
      //   grid = null;
      // }
      self.graph = new G6.Graph({
        container: 'topoChart', // 容器ID
        mode: 'edit',
        // grid: grid,
        width: self.canvasWidth, // 画布宽
        height: 800, // 画布高
        layout: {
          type: 'grid',
          begin: [0, 0], // 可选，
          preventOverlap: true, // 可选，必须配合 nodeSize
          preventOverlapPdding: 20, // 可选
          nodeSize: 30, // 可选
          condense: false, // 可选
          rows: 5, // 可选
          cols: 5, // 可选
          sortBy: 'degree', // 可选
          workerEnabled: true // 可选，开启 web-worker
        }
      });
      /* self.graph.tooltip({
          title: '信息', // @type {String} 标题
          split: ':',  // @type {String} 分割符号
          dx: 0,       // @type {Number} 水平偏移
          dy: 0        // @type {Number} 竖直偏移
        }); */

      /**
       *点击画布
       */
      self.graph.on('click', ev => {
        console.log(ev);
        if (ev.item !== null) {
          self.isBlank = false;
          self.isNode = true;
          self.graph.refresh();
        } else {
          self.isBlank = true;
          self.isNode = false;
          self.infoTitle = '画布';
        }
      });
      /**
       *点击节点
       */
      self.graph.on('node:click', function(ev) {
        console.log(ev);
        self.isNode = true;
        self.activation = ev.item;
        if (ev.item) {
          /* 激活节点后，节点名称input聚焦 */
          self.$nextTick(() => {
            console.log(self.$refs.inputFocusRef);
            self.$refs.inputFocusRef.$el.querySelector('input').focus();
          });
          self.infoTitle = '节点';
          self.name = ev.item.get('model').label;
          self.func = ev.item.get('model').func;
          self.account = ev.item.get('model').account || [];
          self.workflow = ev.item.get('model').workflow;
          self.nodeType = ev.item.get('model').nodeType;
        } else {
          self.infoTitle = '边';
          self.action = ev.item.get('model').action;
        }
        self.color = self.oldColor;
      });
      /**
       * 鼠标移入移出事件改变颜色
       */
      self.graph.on('itemmouseenter', ev => {
        const item = ev.item;
        self.oldColor = item.get('model').color; // 获取节点颜色
        self.graph.update(item, {
          color: '#108EE9'
        });
        self.graph.refresh();
      });
      self.graph.on('itemmouseleave', ev => {
        const item = ev.item;
        self.graph.update(item, {
          color: self.oldColor
        });
        self.graph.refresh();
      }); // 加载资源数据
      /**
       * 提示信息
       */
      /* self.graph.node().tooltip(['label', 'func', 'role', 'color']);
        self.graph.edge().tooltip(['label', 'color']); */
      /**
       * 渲染
       */
      /* self.graph.source(self.nodes, self.edges); */ self.graph.render();
    },
    linkMode() {
      console.log('点击了连接线模式');
    },
    // 添加母线节点
    addBusbar() {
      this.graph.addItem('node', {
        type: 'circle',
        nodeType: 0
      });
      console.log(this.graph);
    },
    // 添加变压器节点
    addTransformer() {
      this.graph.addItem('node', {
        type: 'rect',
        nodeType: 0
      });
    },
    // 添加开关节点
    addSwitch() {
      this.graph.addItem('node', {
        type: 'rhombus',
        nodeType: 0
      });
    },
    // 添加直线
    addLine() {
      this.graph.addItem('edge', {
        type: 'line'
      });
    },
    // 添加曲线
    addSmooth() {
      this.graph.addItem('edge', {
        type: 'smooth'
      });
    },
    // 添加箭头曲线
    addArrowSmooth() {
      this.graph.addItem('edge', {
        type: 'smoothArrow'
      });
    },
    // 添加箭头直线
    addArrowLine() {
      this.graph.addItem('edge', {
        type: 'arrow'
      });
    },
    // 添加折线
    addPolyLine() {
      this.graph.addItem('edge', {
        type: 'polyLine'
      });
    },
    // 拖拽与编辑模式的切换
    changeMode(mode) {
      this.graph.setMode(mode);
    },
    // 删除
    del() {
      this.graph.del();
    },
    // 保存
    save() {
      /* 验证拓扑图名称 */
      if (this.workflowName !== '') {
        const data = this.graph.save();
        if (data.source.nodes.length === 0) {
          this.$message({ type: 'error', message: '拓扑图无内容不能保存' });
          return false;
        }
        /* 验证节点名称 */
        for (const item of data.source.nodes) {
          if (
            item.label === '' ||
            item.label === null ||
            item.label === undefined
          ) {
            this.$message({ type: 'error', message: '节点名称不能为空' });
            return false;
          }
        }
        data.source.name = this.workflowName;
        const json = JSON.stringify(data, null, 2);
        this.$emit('saveData', data.source, this.type);
        console.log(json);
      } else {
        this.$message({ type: 'error', message: '拓扑图名称不能为空' });
      }
    },
    // 更新节点
    update() {
      console.log(this.activation);
      if (this.activation.get('type') === 'node') {
        this.graph.update(this.activation, {
          label: this.name,
          func: this.func,
          account: this.account,
          workflow: this.workflow,
          nodeType: this.nodeType,
          color: this.color
        });
      } else {
        /* 根据ID取出label */
        const label = this.actionList
          .map(item => {
            if (item.id === this.action) {
              return item.label;
            }
          })
          .join('');
        this.graph.update(this.activation, {
          label: label,
          color: this.color,
          action: this.action
        });
      }
    },
    // 清空视图
    clearView() {
      this.type = '';
      this.workflowName = '';
      this.graph.changeData();
    },
    // 更新数据
    source(nodes, edges, name, type) {
      this.type = type;
      this.workflowName = name;
      this.graph.changeData(nodes, edges);
    }
  }
};
</script>

<style lang="less" scoped>
#topoChart {
  border: 1px solid #ebeef5;
  position: relative;
  overflow: hidden;
}

.operating {
  width: 110px;
  position: absolute;
  z-index: 99;
  box-shadow: 1px 1px 4px 0 #0a0a0a2e;
  background: rgba(247, 249, 251, 0.45);

  .tools-title {
    padding: 10px 0;
    background-color: #EBEEF2;
    font-size: 18px;
    text-align: center;
  }
  .choose-btn-group {
    padding: 10px 0;
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;

    .btn {
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
      padding: 5px 10px;
      cursor: pointer;
      border: 1px solid rgba(233, 233, 233, 0);
      img {
        margin-bottom: 5px;
        width: 20px;
        height: 25px;
      }
      &:hover {
      border: 1px solid #e9e9e9;
      color: #767a85;
      border-radius: 2px;
      background: #fafafe;
    }
    }
  }
  .btn-group {
    padding: 10px 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    &:last-of-type {
      border-right: 0;
    }
    .btn {
      padding: 10px 30px;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      align-items: center;
      cursor: pointer;
      border: 1px solid rgba(233, 233, 233, 0);
      i {
        font-size: 20px;
      }
      img {
        margin-bottom: 5px;
        max-width: 30px;
        max-height: 30px;
      }
      &:hover {
        border: 1px solid #e9e9e9;
        color: #767a85;
        border-radius: 2px;
        background: #fafafe;
      }
    }
    .el-form-item {
      margin-bottom: 0 !important;
    }
  }
}

.info-box {
  position: absolute;
  right: 0;
  z-index: 99;
  box-shadow: 1px 1px 4px 0 #0a0a0a2e;
  background: rgba(247, 249, 251, 0.45);
  .title {
    height: 40px;
    padding-left: 10px;
    border-top: 1px solid #dce3e8;
    border-bottom: 1px solid #dce3e8;
    border-left: 1px solid #dce3e8;
    background: rgb(235, 238, 242);
    line-height: 40px;
    span {
      font-size: 14px;
    }
  }
  .content {
    width: 200px;
    height: 800px;
    border-left: 1px solid #e6e9ed;
    padding: 10px;

    /deep/ .el-form .el-input__inner {
      width: 119px;
      padding: 0 5px;
    }
  }
}
</style>
